

/**
 * Modified from Ramin' paper:
 * <RULE> -> a set of <CONDITION PARTS> + <LABEL>
 * <CONDITION PART> -> a set of [<NEIGHBOR> + <HISTORY STEP> + <CONDITION> + <NBVALUE>]s; e.g. N5 in H2 IS 1'
 * <NEIGHBOR> -> one of the neighbors of the neighborhood.
 * <HISTORY STEP> -> a number telling which time step (how far from now) this condition is referring to.
 * <CONDITION> -> [IS / ISNOT]
 * <LABEL> -> a Class Name 
 * <NBVALUE> -> a value from the possible values of the cell, e.g. 0,1,2
 */

#pragma once

////#include "neighborhood2.h"
//#include <vector>
//#include "neighborhood2.h"
#include "partialseacondition.h"

enum SEAMutationType
{
	removepartialcondition,
	addpartialcondition,
	reverseonepartialcondition,
	changeoneneighbor,
	changeonehistorystep,
	changeoneNBvalue,
	changelabel,
	SEAMutationTypes,
};




/**
 * Represents one single rule of Symbiotic EA in this form: <RULE> -> a set of <CONDITION PARTS> + <RESULT>
 */
class SEARule
{
private:
	vector<PartialSEACondition> condition;
	int label;
	int nBRadius;
	int maxHistorySteps;
	void mutate_RemovePartialCondition(void);
	void mutate_AddPartialCondition(void);
	void mutate_ReverseOnePartialCondition(void);
	void mutate_ChangeOneNeighbor(void);
	void mutate_ChangeOneHistoryStep(void);
	void mutate_ChangeOneNBValue(void);
	void mutate_ChangeLabel(void);
	SEARule();
public:	
	SEARule(const SEARule& other);
	SEARule(int radius, int historySteps, int label);
	void mutate (void);
	bool applies (const PixelHistory& pixel) const;
	int getLabel(void) const;
	void initiateRandom (void);
	SEARule& operator= (const SEARule& other);
	friend ostream& operator<< (ostream& stream, const SEARule& searule);
	int getConditionNum() const;
};